#!/usr/bin/env python
# -*- coding: utf-8 -*-

# 注意，一定要装 pip install aioredis==1.3.1

"""
校验token的逻辑：
1. 调用登录接口，产生token

2.调用依赖登录的接口，在请求头中携带token

3.依赖登录的接口，接收到请求，判断是否在headers中携带token

4.携带token，校验是否过期

5.解析token，获取username

6.根据username从redis获取

7.查询到username的token且token相等，我们认为用户登录

8.调用接口返回数据

9.如果其中一项校验不通过，返回对应的失败信息
"""


from fastapi import FastAPI, Request, Query
from aioredis import Redis, create_redis_pool

from routers.users import user_router
from routers.items import item_router
from routers.websocket import websocket_router

from models.database import Base, engine
from config import redis_host, redis_port, redis_db



app = FastAPI(debug=True)



async def create_redis() -> Redis:
    return await create_redis_pool(f"redis://{redis_host}:{redis_port}", db=redis_db, password=None, encoding="utf-8")


async def startup_event():
    app.state.redis = await create_redis()
    print("init redis success")
    # 第一次运行时创建数据库表
    Base.metadata.create_all(bind=engine)
    print('完成创建数据库表...')

app.add_event_handler("startup", startup_event)


async def shutdown_event():
    app.state.redis.close()
    await app.state.redis.wait_closed()
    print("redis closed")

app.add_event_handler("shutdown", shutdown_event)





app.include_router(user_router, prefix="/u", tags=["users"])
app.include_router(item_router, prefix="/i", tags=["items"])
app.include_router(websocket_router, prefix="/socket", tags=["websocket"])


# @app.get("/test", summary="test redis")
# async def test_redis(request: Request, num: int = Query(123, title="参数num")):
#     """
#     等待redis写入，await异步变同步
#     如果不关心结果可以不用await，但是这里下一步要取值
#     必须得先等存完值，然后再取
#     """
#     await request.app.state.redis.set("test", num)
#     # 等待读取值
#     value = await request.app.state.redis.get("test")
#     print(value, type(value))
#     return {"value": value}







if __name__ == '__main__':
    import uvicorn
    uvicorn.run("main:app", host="127.0.0.1", port=8000, reload=True)